# encoding=utf-8
# author:梁子龙
import logging
import re
from datetime import datetime
from typing import Callable

from fastapi import FastAPI
from fastapi.requests import Request
from fastapi.responses import Response, JSONResponse
from jose import jwt
from starlette import status

from config import settings

log = logging.Logger("emp")


async def db_session_middleware(request, call_next: Callable) -> Response:
    """

    :param request:
    :param call_next:
    :return:
    """
    try:
        pass
    except Exception as es:
        log.error(es)


async def verify_token(request: Request, call_next: Callable) -> Response:
    auth_error = JSONResponse({"detail": "非法的token,请重新登陆"}, status_code=status.HTTP_401_UNAUTHORIZED,
                              headers={"WWW-Authenticate": "Bearer"})
    #  api 不要token
    path: str = request.get("path")
    for request_path in settings.WHITE_LIST:
        if re.match(request_path, path):
            return await call_next(request)
    else:
        #
        authorization: str = request.headers.get("Authorization")
        if not authorization:
            return auth_error
        token: str = authorization.split(" ")[1]
        try:
            # 校验token
            res_dict = jwt.decode(token, settings.JWT_SECRET_KEY, algorithms=[settings.ALGORITHM])
            username = res_dict.get("sub").split(":")[1]
            if not username:
                return auth_error
            if datetime.fromtimestamp(res_dict.get("exp")) < datetime.now():  # 超时了
                return auth_error
            request.state.username = username
            return await call_next(request)
        except Exception as e:
            log.error(e)
            return auth_error


def init_middleware(app: FastAPI):
    app.middleware("http")(db_session_middleware)
    app.middleware("http")(verify_token)
